#ifndef batcher_h__
#define batcher_h__
#include "gtl/list.h"
#include "gtl/elist.h"
#include "ivertexbuffer.h"
#include "iindexbuffer.h"
#include "math/matrix44.h"
#include "math/vertex.h"
#include "geometry.h"
//#include <d3dx9math.h>
#include "rendercontext.h"

namespace gecko
{

// Instance of geometry for sending to the renderer.
struct GeometryInstance
{
	ELIST_LINKAGE(GeometryInstance)

	enum Type
	{
		Type_Static,
		Type_Dynamic,
	};

	// Pointer to geometry to render.
	Geometry* m_Geometry;

	// Geometry instance type (static, dynamic)
	Type m_Type;

	GeometryInstance() { m_Type = Type_Static; }
};

// Instance of geometry for sending to the renderer.
struct DynamicGeometryInstance : public GeometryInstance
{
	// Per-instance transformation matrix.
	Matrix44 Tranform;

	DynamicGeometryInstance() { m_Type = Type_Dynamic; }
};

typedef gtl::EList<GeometryInstance> GeometryInstanceList;



struct GeometryBatch
{
	RenderContext RenderContext;
	GeometryInstanceList InstanceList[IVertexBuffer::PT_NUM];

	bool operator ==(const GeometryBatch& rhs)
	{
		return RenderContext == rhs.RenderContext;
	}
};

typedef gtl::List<GeometryBatch> GeometryBatchList;



class VertexCache
{
public:
	static const unsigned short HARD_VERTEX_LIMIT = 0xffff;

	VertexCache();

	bool Initialise(IRenderer* renderer);

	void Begin(IVertexBuffer::ePrimitiveType primitiveType);

	void AddGeometry(GeometryInstance& instance);

	void AddVertex(const Vertex& vertex);

	void End();

	void Flush();

private:
	IVertexBuffer* m_VertexBuffer;
	IIndexBuffer* m_IndexBuffer;
	unsigned short m_VertexCount;
	unsigned char m_VertsPerPrimitive;
	Vertex* m_Vertices;
	unsigned int m_NumDrawCalls;

	unsigned short* m_Indices;
	unsigned short m_IndexCount;

	IVertexBuffer::ePrimitiveType m_PrimitiveType;
};




}

#endif // batcher_h__